<?php
/**
 * Created by PhpStorm.
 * User: vbolshov
 * Date: 13.10.2010
 * Time: 15:35:40
 */

namespace km\db;

use Km,
	km\Cache,
	\PDO;

class CachingActiveRecord extends ActiveRecord {

	/**
	 * @var Cache
	 */
	static protected $cache;
	/**
	 * @var CachingActiveRecord[]
	 */
	static private $registry = array();
	/**
	 * @var int
	 */
	static protected $lifetime;

	static protected function cacheId($id)
	{
		return str_replace('\\', '_', get_called_class()) . '_' . $id;
	}
	/**
	 * @static
	 * @param scalar $id
	 * @return CachingActiveRecord
	 */
	static function findInCache($id)
	{
		if (array_key_exists($cacheId = static::cacheId($id), self::$registry)) {
			return self::$registry[$cacheId];
		} else {
			$class = get_called_class();
			$data = static::getCacheDriver()->getStore($cacheId, function() use ($class, $id) {
				return call_user_func(array($class, 'find'), $id)->fetchOne(PDO::FETCH_ASSOC);
			}, null, static::$lifetime);
			return self::$registry[$cacheId] = new $class($data);
		}
	}
	/**
	 * Increment selected column
	 *
	 * @param string $column
	 * @param int | float $inc
	 * @return mixed the field value after increment
	 */
	function increment($column, $inc = 1, array $additionalFields = array())
	{
		$ret = parent::increment($column, $inc, $additionalFields);
		$this->updateCache();
		return $ret;
	}

	function save()
	{
		if (! $ret = parent::save()) {
			return false;
		}
		$this->updateCache();
		return $ret;
	}

	protected function updateCache()
	{
		static::getCacheDriver()->put(static::cacheId($this->id()), $this->toArray(), null, static::$lifetime);
	}

	function clearCache()
	{
		static::getCacheDriver()->delete(static::cacheId($this->id()));
	}

	/**
	 * @static
	 * @param int $lifetime
	 * @return void
	 */
	static function setLifetime($lifetime)
	{
		static::$lifetime = $lifetime;
	}

	static function setCacheDriver(Cache $driver)
	{
		static::$cache = $driver;
	}

	static function getCacheDriver()
	{
		return static::$cache ?: (static::$cache = Km::getCacheDriver());
	}

}
